﻿using System;
using System.Text;
using System.Drawing;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public static partial class NativeAOT
{
    [UnmanagedCallersOnly(EntryPoint = "kfwt")]
    public static unsafe void kfwt(int n, int k, IntPtr p_ptr, IntPtr x_ptr)
    {
        double* p = (double*)p_ptr.ToPointer();
        double* x = (double*)x_ptr.ToPointer();

        kfwt(n, k, p, x);
    }

    /// <summary>
    /// 快速Walsh变换
    /// void kfwt(int n, int k, double p[], double x[])
    /// </summary>
    /// <param name="n">输入序列的长度。</param>
    /// <param name="k">观测序列长度？</param>
    /// <param name="p">p[n]存放长度为n的给定输入序列。</param>
    /// <param name="x">x[n]返回给定输入序列的Walsh变换序列。</param>
    public static unsafe void kfwt(int n, int k, double* p, double* x)
    {
        int m, l, it, ii, i, j, si;
        double q;

        m = 1;
        l = n;
        it = 2;
        x[0] = 1;
        ii = n / 2;
        x[ii] = 2;
        for (i = 1; i <= k - 1; i++)
        {
            m = m + m;
            l = l / 2;
            it = it + it;
            for (j = 0; j <= m - 1; j++)
            {
                x[j * l + l / 2] = it + 1 - x[j * l];
            }
        }
        for (i = 0; i <= n - 1; i++)
        {
            ii = (int)(x[i] - 1);
            x[i] = p[ii];
        }
        l = 1;
        for (i = 1; i <= k; i++)
        {
            m = n / (2 * l) - 1;
            for (j = 0; j <= m; j++)
            {
                it = 2 * l * j;
                for (si = 0; si <= l - 1; si++)
                {
                    q = x[it + si] + x[it + si + l];
                    x[it + si + l] = x[it + si] - x[it + si + l];
                    x[it + si] = q;
                }
            }
            l = 2 * l;
        }
        return;
    }

    /*
    // 快速Walsh变换例
      int main()
      { 
          int i;
          double p[8],x[8];
          for (i=0; i<=7; i++) p[i]=i+1;
          kfwt(8,3,p,x);
          for (i=0; i<=7; i++) 
              cout <<"x(" <<i <<")=" <<x[i] <<endl;
          return 0;
      }
    */
}

